#!/bin/bash
LLVM_PROJECT_DIR="${PWD}/llvm-project"
LLVM_CI_DIR="${PWD}/llvm-ci"
TOOLCHAIN_PATH=$(find "${PWD}" -maxdepth 1 -type d -name 'clang-*')
TOOLCHAIN_BIN_PATH="${TOOLCHAIN_PATH}/bin"
export PATH="${TOOLCHAIN_BIN_PATH}:${PATH}"
BUILD_DIR="${PWD}"
TARGET_TRIPLE="arm-linux-ohos"
EXTRA_FLAGS="-march=armv7-a"
CLANG_FLAGS="clang_flags.txt"
PHONE_MODEL_NAME="LIO ELS"
#LIFE_TIME_FARM_GROUP="7"
PHONE_GROUP_NAME="LLVM-CI"
DISABLED_TESTS="arm-linux-ohos-asan.txt"
PHONE_SYMBOLIZER_PATH="/system/bin/llvm-symbolizer"

export disabled_tests_dir="${LLVM_CI_DIR}/resources/disabled_tests"
export enabled_tests_dir="${LLVM_CI_DIR}/resources/enabled_tests"
pushd "${PWD}/llvm-project"
cmake -G Ninja \
      -DLLVM_ENABLE_PROJECTS='clang;clang-tools-extra;libcxx;libcxxabi;libunwind;lldb;compiler-rt;lld;polly' \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX="${PWD}/install" \
      "${LLVM_PROJECT_DIR}/llvm"
ninja install-llvm-config
export LLVM_CONFIG_PATH="${PWD}/install/bin/llvm-config"
popd
export SYSROOT="${PWD}/sysroot/${TARGET_TRIPLE}"
export RT_COMPILE_FLAGS="-v --target=${TARGET_TRIPLE} --sysroot=${SYSROOT} ${EXTRA_FLAGS}"


TMP_DIR="${BUILD_DIR}"
mkdir -p "${TMP_DIR}"
pushd "${TMP_DIR}"

cmake \
        ${LLVM_PROJECT_DIR}/compiler-rt \
        -G Ninja \
        -DCMAKE_MODULE_PATH="${LLVM_CI_DIR}/resources/cmake" \
        -DCMAKE_SYSTEM_NAME=OHOS \
        -DCMAKE_AR="${TOOLCHAIN_BIN_PATH}/llvm-ar" \
        -DLLVM_CONFIG_PATH="${LLVM_CONFIG_PATH}" \
        -DCMAKE_ASM_COMPILER_TARGET="${TARGET_TRIPLE}" \
        -DCMAKE_ASM_FLAGS="${RT_COMPILE_FLAGS}" \
        -DCMAKE_C_COMPILER="${TOOLCHAIN_BIN_PATH}/clang" \
        -DCMAKE_C_COMPILER_TARGET="${TARGET_TRIPLE}" \
        -DCMAKE_C_FLAGS="${RT_COMPILE_FLAGS}" \
        -DCMAKE_CXX_COMPILER="${TOOLCHAIN_BIN_PATH}/clang++" \
        -DCMAKE_CXX_COMPILER_TARGET="${TARGET_TRIPLE}" \
        -DCMAKE_CXX_FLAGS="${RT_COMPILE_FLAGS}" \
        -DCMAKE_EXE_LINKER_FLAGS="${RT_COMPILE_FLAGS}" \
        -DCOMPILER_RT_BUILD_BUILTINS=OFF \
        -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
        -DCOMPILER_RT_BUILD_MEMPROF=OFF \
        -DCOMPILER_RT_BUILD_PROFILE=ON \
        -DCOMPILER_RT_BUILD_SANITIZERS=ON \
        -DCOMPILER_RT_BUILD_XRAY=OFF \
        -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
        -DCOMPILER_RT_INCLUDE_TESTS=ON \
        -DCOMPILER_RT_TEST_COMPILER="${TOOLCHAIN_BIN_PATH}/clang" \
        -DCOMPILER_RT_TEST_COMPILER_CFLAGS="${RT_COMPILE_FLAGS}"

echo "RT_COMPILE_FLAGS = ${RT_COMPILE_FLAGS}" >> "${BUILD_DIR}/${CLANG_FLAGS}"

popd
ninja AsanDynamicUnitTests
ninja AsanUnitTests
export hdc="/usr/bin/hdc"
#get devices
hdc list targets
function cleanup_phone() {
      if $(echo "${TARGET_TRIPLE}" | grep -qv "x86"); then # arm64 || arm32
        cleandir="${1:?"clean dir no set"}"
        hdc shell "rm -rf ${cleandir}"
        hdc shell "rm -f ${PHONE_SYMBOLIZER_PATH}"
      fi
    }

disabled_tests_path="${disabled_tests_dir}/${DISABLED_TESTS}"
if [ -f "${disabled_tests_path}" ]; then
    disabled="$(cat ${disabled_tests_path} | tr '\n' '|' | sed -e "s/|$//g")"
    for dir in "${BUILD_DIR}/test/asan/"*; do
        if [ -d "${dir}" ]; then
        RUN_TESTS+="$(python3 bin/llvm-lit --show-tests ${dir} 2>/dev/null \
                | grep "AddressSanitizer" \
                | grep -v -E "${disabled}" \
                | sed -e "s/  //" \
                | tr '\n' '|')" || true
        fi
    done
    # remove trailing |
    export RUN_TESTS="$(echo "${RUN_TESTS}" | sed -e "s/|$//g")"
    echo "tests to run:"
    echo "${RUN_TESTS}"
fi

if $(echo "${TARGET_TRIPLE}" | grep -qv "x86"); then # arm64 || arm32
    # global-overflow-bfd.cpp test need cross-compilation with gnu-ld linker,
    # but default gnu linker doesn't support arm/aarch64 targets,
    # so we replace it with one which supports
    sudo ln -fs /usr/bin/aarch64-linux-gnu-ld /usr/bin/ld.bfd
    HOS_TMPDIR="/data/local/tmp/Output"
    hdc shell mount -o rw,remount / || EXIT_CODE=$?
    # remove artifacts from previous run, if exists
    cleanup_phone "${HOS_TMPDIR}" || EXIT_CODE=$?
    hdc shell "mkdir /data/local/tmp/Output"
    # push all libraries needed for tests
    for file in $(find "${TOOLCHAIN_PATH}" -name "libclang_rt.asan*" | grep "${TARGET_TRIPLE}/"); do
    hdc file send "${file}" "${HOS_TMPDIR}/$(basename ${file})" || EXIT_CODE=$?
    done
    hdc file send "${TOOLCHAIN_PATH}/lib/${TARGET_TRIPLE}/c++/libc++.so" "${HOS_TMPDIR}/libc++.so" || EXIT_CODE=$?

    # FileCheck expects symbolized output,
    # so we have to push llvm-symbolizer to target,
    # and make sure, that it is on PATH
    SYMBOLIZER_NAME="llvm-symbolizer-arm"
    hdc shell mount -o rw,remount / || EXIT_CODE=$?
    hdc file send "${SYMBOLIZER_NAME}" "${HOS_TMPDIR}/${SYMBOLIZER_NAME}" || EXIT_CODE=$?
    hdc shell "chmod +x ${HOS_TMPDIR}/${SYMBOLIZER_NAME}" || EXIT_CODE=$?
    hdc shell "ln -sf ${HOS_TMPDIR}/${SYMBOLIZER_NAME} ${PHONE_SYMBOLIZER_PATH}" || EXIT_CODE=$?

    # for *-ohos targets we need ld-musl linker to run tests
    if [[ "${TARGET_TRIPLE}" =~ ohos ]]; then
    ARCH="$(echo "${TARGET_TRIPLE}" | cut -f1 -d'-')"
    LINKER_NAME="ld-musl-${ARCH}.so.1"
    LINKER="${SYSROOT}/usr/lib/${LINKER_NAME}"
    export DEVICE_MUSL_LINKER="${HOS_TMPDIR}/${LINKER_NAME}"
    hdc file send "${LINKER}" "${DEVICE_MUSL_LINKER}" || EXIT_CODE=$?
    hdc shell "chmod +x ${HOS_TMPDIR}/${LINKER_NAME}"
    else
    # for *-hos targets we need to copy libm.so
    hdc file send "${SYSROOT}/usr/lib/libm.so" "${HOS_TMPDIR}/libm.so"
    fi
fi


TARGET_UNIT_TEST_DIR="${HOS_TMPDIR}/Unit"
    hdc shell mkdir -p "${TARGET_UNIT_TEST_DIR}" || EXIT_CODE=$?
    LOCAL_UNIT_TEST_DIRS="${PWD}/lib/asan/tests/default ${PWD}/lib/asan/tests/dynamic"
    for unit_dir in ${LOCAL_UNIT_TEST_DIRS}; do
      hdc file send ${unit_dir}/* "${TARGET_UNIT_TEST_DIR}" || EXIT_CODE=$?
    done
    for unit_dir in ${LOCAL_UNIT_TEST_DIRS}; do
      for test in ${unit_dir}/*; do
        testname="$(basename "${test}")"
        unittest_disabled="${disabled_tests_dir}/${testname}-${TARGET_TRIPLE}.txt"
        if [ -f "${unittest_disabled}" ]; then
          GTEST_FILTER="GTEST_FILTER=-$(cat "${unittest_disabled}" | tr '\n' ':')"
          echo "disabled unit test list:"
          cat "${unittest_disabled}"
        fi
        hdc shell "LD_LIBRARY_PATH=${HOS_TMPDIR} ${GTEST_FILTER} ${DEVICE_MUSL_LINKER} ${TARGET_UNIT_TEST_DIR}/${testname}" || EXIT_CODE=$?
      done
    done

LIT_FILTER="${RUN_TESTS}" ninja -v check-asan || EXIT_CODE=$?
LIT_FILTER="${RUN_TESTS}" ninja -v check-asan-dynamic || EXIT_CODE=$?
